home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / jed10.zip / WHATAMI.ASM < prev    next >
Assembly Source File  |  1993-02-26  |  6KB  |  139 lines

  1. ;---------------------------------------------------------------
  2. ;                             WHATAMI.ASM
  3. ;
  4. ; Program to demonstrate runtime detection of the installed CPU
  5. ;
  6. ; Many thanks to Nicholas Wilt for providing me the algorithm!
  7. ;
  8. ;                                      by Jeff Duntemann
  9. ;                                      MASM/TASM
  10. ;                                      Last update 2/9/92
  11. ;---------------------------------------------------------------
  12.  
  13. ;----------------------------|
  14. ;    BEGIN STACK SEGMENT     |
  15. ;----------------------------|
  16. MYSTACK    SEGMENT STACK        ; STACK word ensures loading of SS by DOS
  17.  
  18.            DB      64 DUP ('STACK!!!') ; This reserves 512 bytes for the stack
  19.  
  20. MYSTACK    ENDS
  21. ;----------------------------|
  22. ;     END STACK SEGMENT      |
  23. ;----------------------------|
  24.  
  25.  
  26. ;----------------------------|
  27. ;     BEGIN DATA SEGMENT     |
  28. ;----------------------------|
  29. MyData     SEGMENT
  30.  
  31. MsgTbl     DB      "You have an 88. "
  32.            DB      "You have a 286. "
  33.            DB      "You have a 386. "
  34.            DB      "You have a 486. "
  35.  
  36. MyData     ENDS
  37. ;----------------------------|
  38. ;      END DATA SEGMENT      |
  39. ;----------------------------|
  40.  
  41. ;----------------------------|
  42. ;     BEGIN CODE SEGMENT     |
  43. ;----------------------------|
  44.  
  45. MyProg     SEGMENT
  46.  
  47.            assume CS:MyProg,DS:MyData
  48.  
  49.  
  50. ; CPUID -- determines the installed CPU
  51. ;
  52. ;          Returns a value in AL that has the following meaning:
  53. ;          0 - 8086 or 8088
  54. ;          1 - 80286
  55. ;          2 - 80386, DX or SX
  56. ;          3 - 80486
  57.  
  58. CPUID      PROC
  59. .386
  60.            ; Assume we have an 8086/8088 for now...
  61.            xor  DX,DX       ; Clear DX to 0
  62.            push DX          ; Push 16 bits of 0's on the stack
  63.            popf             ; Pop 16 bits of 0's off stack & into flags
  64.            pushf            ; Push state of flags back onto stack..
  65.            pop  AX          ; ..so that we can pop them off & look at them
  66.            cmp  AX,0F000H   ; Test the high 4 bits of what was in flags
  67.            je   Done        ; If top 4 bits are set, it's an 8086/8088
  68.            inc  DX          ; Otherwise, we have at least a 286, so we can
  69.                             ;   increment the ID code & keep on testing..
  70.            push 0F000H      ; Push the value 0F000H on the stack
  71.            popf             ; Pop 0F000H off stack into the flags
  72.            pushf            ; Push state of flags back onto stack..
  73.            pop  AX          ; ..so that we can pop them off & look at them
  74.            and  AX,0F000H   ; Check to see if they still contain 0F000H
  75.            jz   Done        ; This time, if the flags are *not* 0F000H,
  76.                             ;   we have a 286
  77.            inc  DX          ; Otherwise, we have at least a 386, so we can
  78.                             ;   increment the ID code & keep on testing..
  79.  
  80. ; Testing for the 486 -- algorithm from Hummel
  81.            mov  ECX,ESP     ; Save the stack pointer in EDX
  82.            and  ESP,NOT 3   ; Force stack pointer to align on a DWORD
  83.            pushfd           ; Push extended flags register onto the stack
  84.            pop  EAX         ; Pop extended flags values off stack into EAX
  85.            mov  EBX,EAX     ; Save a copy of the extended flags for later
  86.            xor  EAX,00040000H      ; Try to toggle AC bit in extended flags
  87.            push EAX         ; Push flags test value from EAX onto stack..
  88.            popfd            ; ..and pop it back into the extended flags reg.
  89.            pushfd           ; Push extended flags value back onto stack..
  90.            pop  EAX         ; ..and pop it back into EAX for inspection
  91.            xor  EAX,EBX     ; Compare altered against unaltered flags value
  92.            jz   FixESP      ; If toggle of AC bit didn't "take," it's a 386..
  93.            inc  DX          ; ..but if it did, we have a 486, so inc DX to 3
  94.  
  95. FixESP:    mov  ESP,ECX     ; Put the original stack pointer back into ESP
  96. Done:      mov  AX,DX       ; Let's return the CPU code in AX
  97.            ret              ; and go back to the caller
  98.  
  99. CPUID      ENDP
  100.  
  101.  
  102. ; BEGIN MAIN PROGRAM
  103.  
  104. Main       PROC
  105.  
  106. Start:     ; This is where program execution begins:
  107.            mov  AX,MyData   ; Set up our own data segment address in DS
  108.            mov  DS,AX       ; Can't load segment reg. directly from memory
  109.  
  110.            ; Identifying the CPU is just a matter of calling the CPUID proc:
  111.            call CPUID       ; Go out and test for the installed CPU
  112.            push AX          ; Save the return code on stack for ERRORLEVEL
  113.  
  114.            ; Now we print the message based on the CPU code:
  115.            xor  AH,AH       ; Clear AH so the code stands alone
  116.            mov  DI,AX       ; Put AL with CPU ID code value into DI
  117.            mov  CL,4        ; Load shift count value into CL
  118.            shl  DI,CL       ; Multiply code by 16 to get offset into table
  119.            lea  DX,MsgTbl   ; Load address of start of message table into BX
  120.            add  DX,DI       ; Add calculated offset to address
  121.            mov  CX,16       ; All messages in table are 16 bytes long
  122.            mov  BX,1        ; Selects DOS file handle #1: Standard Output
  123.            mov  AH,40H      ; Select DOS service 40: Print String
  124.            int  21H         ; Make the DOS call
  125.  
  126.            pop  AX          ; Make sure code is still in AL
  127.            mov  AH,4CH      ; Terminate process DOS service
  128.            int  21H         ; Control returns to DOS
  129.  
  130. Main       ENDP
  131.  
  132. MyProg     ENDS
  133.  
  134. ;----------------------------|
  135. ;      END CODE SEGMENT      |
  136. ;----------------------------|
  137.  
  138.            END Start    ; The procedure named Start becomes the main program
  139.